#define _EKOS_KERNEL_C_

#include <kernel/kernel.h>
#include <kernel/console.h>

static char buf[RL_BUFLEN];

char *
readline(const char *prompt)
{
	 int i, c, echoing;

	 if (prompt != NULL)
		  cprintf("%s", prompt);

	 i = 0;
	 echoing = iscons(0);
	 while (1) {
		  c = getchar();
		  if (c < 0) {
			   cprintf("read error: %e\n", c);
			   return NULL;
		  } else if (c >= ' ' && i < RL_BUFLEN-1) {
			   if (echoing)
					cputchar(c);
			   buf[i++] = c;
		  } else if (c == '\b' && i > 0) {
			   if (echoing)
					cputchar(c);
			   i--;
		  } else if (c == '\n' || c == '\r') {
			   if (echoing)
					cputchar(c);
			   buf[i] = 0;
			   return buf;
		  }
	 }
}

static void
putch(int ch, int *cnt)
{
	 cputchar(ch);
	 *cnt++;
}

int
vcprintf(const char *fmt, va_list ap)
{
	 int cnt = 0;

	 vprintfmt((void*)putch, &cnt, fmt, ap);
	 return cnt;
}

int
cprintf(const char *fmt, ...)
{
	 va_list ap;
	 int cnt;

	 va_start(ap, fmt);
	 cnt = vcprintf(fmt, ap);
	 va_end(ap);

	 return cnt;
}

bool console_enabled;
bool log_enabled;
bool klog_mutexed;

struct mutex_t kprintf_lock;

uint8_t lock = 0;

int
vkprintf(const char *fmt, va_list ap)
{
	 if (klog_mutexed)
		  mutex_lock(&kprintf_lock);
	 else sl_lock(&lock);
	 
	 if (console_enabled)
		  vcprintf(fmt, ap);
	 if (log_enabled)
		  vkpprintf(&klog_pipe, fmt, ap);

	 if (klog_mutexed)
	 	  mutex_unlock(&kprintf_lock);
	 else sl_release(&lock);

	 return 0;
}

int
kprintf(const char *fmt, ...)
{
	 va_list ap;
	 int cnt;

	 va_start(ap, fmt);
	 cnt = vkprintf(fmt, ap);
	 va_end(ap);

	 return cnt;
}
